const EventEmitter = require('events');
const fs = require('fs')
class ReadStream extends EventEmitter {
    constructor(path,options){
        super()
        this.path = path;
        this.flags = options.flags || 'r'; //
        this.highWaterMark = options.highWaterMark || 64*1024;
        this.start = options.start||0;
        this.end = options.end;
        this.emitClose = options.emitClose || true;
        this.encoding = options.encoding;

        // 控制是否流动，当用户监听了data事件后，就变成true
        this.flowing = false 
        this.offset = this.start; // 偏移量

        this.open()

        this.on('newListener',(eventName)=>{
            if(eventName === 'data'){ //用户监听了data事件
                this.flowing = true
                this.read()
            }
        })
    } 
    destory(err){
        if(err){
            this.emit('error')
        }
        if(this.fd){
            fs.close(this.fd,()=>{
                this.emit('close')
            })
        }
    }
    open(){
        // 异步操作，fd不会第一时间获取
        fs.open(this.path,this.flags,(err,fd)=>{
            if(err){
                this.destory()
            }
            this.fd = fd
            this.emit('open',fd)
        })
    }
    read(){
        // fs.open异步操作，fd不会第一时间获取
        if(typeof this.fd !== 'number'){
            return this.once('open',()=>this.read())
        }
        console.log('用户监听了data，开始不停读取',this.fd);
        const howMuchToRead = this.end ? Math.min(this.highWaterMark,(this.end-this.offset+1)):this.highWaterMark
        // 用户会保留 每次读出的结果，如果用同一个内存地址 会到，缓存的都是最后一次的
        const buffer = Buffer.alloc(this.highWaterMark)
        fs.read(this.fd,buffer,0,howMuchToRead,this.offset,(err,bytesRead)=>{
            if (err) return this.destory(err);
            if (bytesRead == 0) {
                this.emit('end'); // 如果读取不到内容 说明整个流程就完成了 触发end事件
                return this.destory(); // 最终销毁即可
            }
            this.offset += bytesRead;
            this.emit('data', buffer.slice(0, bytesRead));
            if (this.flowing) {
                this.read()
            }
        })
    }
    pause(){
        if(this.flowing){
            this.flowing = false
        }
    }
    resume(){
        if(!this.flowing){
            this.flowing = true
            this.read()
        }
    }
    pipe(ws){
        this.on('data',chunk=>{
            let flag = ws.write(chunk)
            if(!flag){
                this.pause()
            }
        })

        this.on('end',()=>{
            ws.end()
        })
        ws.on('drain',()=>{
            this.resume()
        })
    }
}


module.exports = ReadStream